package util

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"time"

	"github.com/goccy/go-json"

	"gitee.com/asphodelus_dev/go-s3-local/fs"
)

func IsDir(path string) bool {
	fileInfo, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			return false // 路径不存在，不是文件夹
		}
		return false // 获取文件信息出错
	}

	return fileInfo.IsDir()
}

func CopyFile(sourceFile, destinationFile string) error {
	source, err := os.Open(sourceFile)
	if err != nil {
		return fmt.Errorf("无法打开源文件：%s", err.Error())
	}
	defer source.Close()

	destination, err := os.Create(destinationFile)
	if err != nil {
		return fmt.Errorf("无法创建目标文件：%s", err.Error())
	}
	defer destination.Close()

	_, err = io.Copy(destination, source)
	if err != nil {
		return fmt.Errorf("无法复制文件内容：%s", err.Error())
	}

	return nil
}

func IsPathExist(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true // 路径存在
	}

	if os.IsNotExist(err) {
		return false // 路径不存在
	}

	return false // 获取路径信息出错
}

//	func FileType(path string) (string, error) {
//		file, err := os.Open(path)
//		if err != nil {
//			return "", err
//		}
//		buf := make([]byte, 512)
//		_, err = file.Read(buf)
//		if err != nil {
//			return "", err
//		}
//		return http.DetectContentType(buf), nil
//	}
//
//	func SaveFile(filePath string, data []byte) error {
//		// 创建目录
//		err := os.MkdirAll(filepath.Dir(filePath), 0o755)
//		if err != nil {
//			return err
//		}
//
//		// 写入文件
//		err = os.WriteFile(filePath, data, 0o644)
//		if err != nil {
//			return err
//		}
//
//		return nil
//	}
func SaveChunkFile(filePath string, data []byte) error {
	// 创建目录
	err := os.MkdirAll(filepath.Dir(filePath), 0o755)
	if err != nil {
		return err
	}

	// 写入文件
	err = os.WriteFile(filePath, data, 0o644)
	if err != nil {
		return err
	}

	return nil
}

// SaveFileWithMetaInfo 根据元信息保存文件到文件系统
func SaveFileWithMetaInfo(filePath, fileType, fileName string, fileSize int64, fileModTime time.Time, reader io.Reader) error {
	if filePath[len(filePath)-1:] == "/" {
		err := os.MkdirAll(filePath, 0o755)
		if err != nil {
			return err
		}
	} else {
		chunks, err := fs.SplitFile(reader, 8<<20)
		if err != nil {
			return err
		}
		metaInfo := fs.Metadata{
			Name:   fileName,
			Size:   fileSize,
			Type:   fileType,
			Time:   fileModTime,
			Chunks: chunks,
		}
		marshal, err := json.Marshal(&metaInfo)
		if err != nil {
			return err
		}
		metaInfoPath := filePath + ".meta"
		err = os.MkdirAll(filepath.Dir(metaInfoPath), 0o755)
		if err != nil {
			return err
		}
		err = os.WriteFile(metaInfoPath, marshal, 0o644)
		if err != nil {
			return err
		}
	}
	return nil
}

func FileTypeFromMetaInfo(filePath string) (string, error) {
	metaInfoPath := filePath + ".meta"
	file, err := os.ReadFile(metaInfoPath)
	if err != nil {
		return "", err
	}
	var metaInfo fs.Metadata
	err = json.Unmarshal(file, &metaInfo)
	if err != nil {
		return "", err
	}
	return metaInfo.Type, nil
}

// FileReaderFromMetaInfo 根据路径反序列化元信息，从元信息中获取分片路径得到最终文件的Reader
func FileReaderFromMetaInfo(filePath string) (io.Reader, error) {
	metaInfoPath := filePath + ".meta"
	file, err := os.ReadFile(metaInfoPath)
	if err != nil {
		return nil, err
	}
	var metaInfo fs.Metadata
	err = json.Unmarshal(file, &metaInfo)
	if err != nil {
		return nil, err
	}
	var paths []string
	for _, chunk := range metaInfo.Chunks {
		chunkFilePath := fs.PathFromHash(chunk)
		paths = append(paths, chunkFilePath)
	}
	return fs.MultiDecompressedReader(paths)
}
